#pragma once
#include "stdafx.h"


/*======================================================================*/
/*						 Vector3 Linked List */
/*======================================================================*/

vector3link* NullVector3(){return 0;};

int vector3link::InsertAfter(vector3link* after)
{
	if (list!=after->list) return 0;
	Unlinkvector3(this);
	vector3list* l=after->list;
	if (after==l->tail)
	{
		this->next=0;
		this->prev=after;
		after->next=this;
		l->tail=this;
	}
	else
	{
		this->prev=after;
		after->next->prev=this;
		this->next=after->next;
		after->next=this;
	};
	list->count++;
	return 1;
};

int vector3link::InsertBefore(vector3link* before)
{
	if (list!=before->list) return 0;
	Unlinkvector3(this);
	vector3list* l=before->list;
	if (before==l->head)
	{
		this->prev=0;
		this->next=before;
		before->prev=this;
		l->head=this;
	}
	else
	{
		this->next=before;
		before->prev->next=this;
		this->prev=before->prev;
		before->prev=this;
	};
	list->count++;
	return 1;
};










/*======================================================================*/
/*						 Linked List */
/*======================================================================*/

/* ***********
 * PRIVATE *
 ************/
btV3List::btV3List()
{
	_head	=	0;//_NULL_LINK;
	_tail	=	0;//_NULL_LINK;
	_Count	=	0;
};

btV3List* btV3List::Copy()
{
	btV3List* copy = new btV3List();
	btV3Link* lnk = _head;
	while (lnk!=0)
	{
		copy->AddLast(lnk->_v);
		lnk=lnk->_next;
	};
	return copy;
};

btV3List::~btV3List()
{
	while (_head != 0)
	{
		btV3Link* temp=_head->_next;
		delete _head;
		_head=temp;
	};	
};

btV3Link* btV3List::AddLast(btVector3* pV)
{
	btV3Link* lnk	=	new btV3Link();
	lnk->_v			=	pV;
	lnk->_list		=	this;
	
	if (_head==0)
	{
		_head		=	lnk;
		lnk->_prev	=	0;
	}
	else
	{
		_tail->_next=	lnk;
		lnk->_prev	=	_tail;
	};
	_tail			=	lnk;
	lnk->_next		=	0;
	_Count++;
	return lnk;
};

btV3Link* btV3List::AddFirst(btVector3* pV)
{
	btV3Link* lnk	=	new btV3Link();
	lnk->_v			=	pV;
	lnk->_list		=	this;
	
	if (_tail==0)
	{
		_tail		=	lnk;
		lnk->_next	=	0;
	}
	else
	{
		_head->_prev=	lnk;
		lnk->_next	=	_head;
	};
	_head			=	lnk;
	lnk->_prev		=	0;
	_Count++;
	return lnk;
};

btV3Link* btV3List::Find(btVector3* pV)
{
	if (_head==0) return 0;
	btV3Link* l = _head;
	while (l!=0)
	{
		if (l->_v==pV) return l;
		l=l->_next;
	};
	return 0;
};



btV3Link::btV3Link(){_v=0;};
btV3Link::~btV3Link(){btV3Unlink(this);};

btV3Link* btV3NullLink(){return 0;};

inline void btV3Unlink(btV3Link* lnk)
{
	btV3List* l = lnk->_list;
	
	if (lnk==l->_head)
	{
		if (lnk==l->_tail)
		{
			l->_head=0;
			l->_tail=0;
		}
		else
		{
			l->_head=lnk->_next;
			l->_head->_prev=0;
		};
	}
	else
	{
		if (lnk==l->_tail)
		{
			l->_tail=l->_tail->_prev;
			l->_tail->_next=0;
		}
		else
		{
			lnk->_next->_prev=lnk->_prev;
			lnk->_prev->_next=lnk->_next;
		};
	};
	lnk->_next=0;
	lnk->_prev=0;
	lnk->_list->_Count--;
};

int btV3Link::InsertAfter(btV3Link* after)
{
	if (_list!=after->_list) return 0;
	btV3Unlink(this);
	btV3List* l=after->_list;
	if (after==l->_tail)
	{
		this->_next=0;
		this->_prev=after;
		after->_next=this;
		l->_tail=this;
	}
	else
	{
		this->_prev=after;
		after->_next->_prev=this;
		this->_next=after->_next;
		after->_next=this;
	};
	_list->_Count++;
	return 1;
};

int btV3Link::InsertBefore(btV3Link* before)
{
	if (_list!=before->_list) return 0;
	btV3Unlink(this);
	btV3List* l=before->_list;
	if (before==l->_head)
	{
		this->_prev=0;
		this->_next=before;
		before->_prev=this;
		l->_head=this;
	}
	else
	{
		this->_next=before;
		before->_prev->_next=this;
		this->_prev=before->_prev;
		before->_prev=this;
	};
	_list->_Count++;
	return 1;
};

int btV3Link::Swap(btV3Link* l2)
{
	if (this==l2){return 0;};
	if (l2->_list!=_list){return 0;};
	
	if (_next==l2)
	{
		if (this==_list->_head){_list->_head=l2;};
		if (l2==_list->_tail){_list->_tail=this;};
		
		if (l2->_next != 0){l2->_next->_prev=this;};
		if (_prev != 0){_prev->_next=l2;};
		
		_next=l2->_next;
		l2->_prev=this->_prev;
		_prev=l2;
		l2->_next=this;
		
		return 1;
	};
	
	if (_prev==l2)
	{
		if (this==_list->_tail){_list->_tail=l2;};
		if (l2==_list->_head){_list->_head=this;};
		
		if (l2->_prev != 0){l2->_prev->_next=this;};
		if (_next != 0){_next->_prev=l2;};
		
		_prev=l2->_prev;
		l2->_next=this->_next;
		_next=l2;
		l2->_prev=this;
		
		return 1;
	};
	
	if ((_next==0) && (_prev==0)) return 0;
	
	// swap head/tail ?
	if (this==_list->_head)
	{
		_list->_head=l2;
	}
	else
	{
		if (l2==_list->_head)
		{
			_list->_head = this;
		}
	};
	
	if (this==_list->_tail)
	{
		_list->_tail=l2;
	}
	else
	{
		if (l2==_list->_tail)
		{
			_list->_tail = this;
		}
	};
	
	btV3Link* n1 = _next;
	btV3Link* p1 = _prev;
	btV3Link* n2 = l2->_next;
	btV3Link* p2 = l2->_prev;
	
	_next=n2;
	_prev=p2;
	l2->_next=n1;
	l2->_prev=p1;
	
	if (n1!=0){n1->_prev=l2;};
	if (p1!=0){p1->_next=l2;};
	if (n2!=0){n2->_prev=this;};
	if (p2!=0){p2->_next=this;};

	return 1;
};

